home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekikoh Dennoh Club 1
/
Gekikoh Dennoh Club Vol. 1 (Japan).7z
/
Gekikoh Dennoh Club Vol. 1 (Japan) (Track 1).bin
/
tools
/
xb
/
xb.has
< prev
next >
Wrap
Text File
|
1997-03-05
|
51KB
|
3,096 lines
*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
*
* xb.has …… ぺけ-BASICのコンパイラ本体(メイン)
*
*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
.include doscall.mac
.include iocscall.mac
.include fefunc.h
.include variable.h
.xref statement_check
.xref first_check_a5
.xref first_check_a5_in_line
.xref 行末まで飛ばし
.xref hash
.xref hash_label特別
.xref make_hash_istable
.xref stat解釈
.xref variable_check
.xref math解釈
.xref function解釈
.xref function_check
.xref global変数リスト作成
.xref 未宣言をint_sub
.xref system変数table作成
.xref dim_init_data
.xref int定数get
.xref one_check
.xref 型get
.xref 型getS
.xref 名前登録
.xref label_sub
.xref If_end
.xref Else
.xref else_check
.xref basic_exec
.text
.even
start:
lea.l $10(a0),a0
suba.l a0,a1
movem.l a0-a1,-(sp)
DOS _SETBLOCK
move.l #_WORK,d2
move.l #$c0_0000,-(sp)
DOS _MALLOC
andi.l #$ff_fff0,d0
cmp.l d2,d0
bcs mem_err0
move.l d0,d1
move.l d0,(sp)
DOS _MALLOC * メモリ最大確保
movea.l d0,a6
lea.l a6保存(pc),a1
move.l d0,(a1)
add.l d2,d0
movea.l d0,a4
lea.l -$20(a4),sp * 万が一の時のための余裕
move.l d0,SPinit
add.l a6,d1
move.l d1,mem_last
moveq #0,d7 * フラグリセット
moveq #-1,d0
move.l d7,errorno
move.l d7,行数
move.w d7,EXITcode
move.w d7,fkeyflag
move.b d7,sinitFLAG
move.w d0,関数file数
move.w d0,breakcheck
move.w d0,tagFP
movem.l d0/d7,EXTENDmask * OFFmask/ONmask
move.w d7,_FREEMEM(a6)
move.b d7,cnf_filename
move.b d7,tag_filename
move.b d7,ed_filename
* lea.l $c4-$10(a0),a0 * 起動されたコマンド名
lea.l $80-$10(a0),a0 * 起動されたドライブ+パス名
lea.l 起動dir,a1
@@:
move.b (a0)+,(a1)+
bne @b
bsr com_est
bsr make_hash_istable
** ** ** ** ** ** 初期化終了
pea.l endendend(pc)
move.w #$fff1,-(sp) * どうやらINTERRUPT押したらここに飛んでくるらしいぞ
DOS _INTVCS
addq.l #6,sp
pea.l _BREAK(pc)
move.w #$2d,-(sp) * CTRL+C によるブレークチェックフラグのセット
DOS _INTVCS
lea.l _breakflag(pc),a0
clr.w (a0)+ * ブレークチェックフラグのリセット
move.l d0,(a0) * 元のベクタアドレス
move.w #-1,(sp)
DOS _BREAKCK
move.w d0,breakcheck
move.w #2,(sp) * BREAK KILL
DOS _BREAKCK
addq.l #6,sp
move.w #$fe02,sinitASK * always-never(deafault)
move.w #-1,関数file数
* xb.cnf (basic.cnf) を読み込む。
bsr cnf_read
movem.l EXTENDmask,d0/d1
and.l d0,d7 * OFFmask
or.l d1,d7 * ONmask
clr.l 行数
* 外部関数を読み込む
bsr func_read
move.l a4,strbuf
adda.l #strbufSIZE,a4
move.l a4,nest_work
adda.l #nest_workSIZE,a4
move.l a4,program_area
* フリーエリア指定サイズ確保
moveq #0,d0
move.w _FREEMEM(a6),d0
bne @f
move.w #$100,d0 * default
@@:
moveq #10,d1
lsl.l d1,d0 * 1K 倍
lea.l (a4,d0.l),a1
cmpa.l mem_last,a1
bhi mem_err1
move.l a4,MEM1
move.l a1,MEM2
move.l a1,mem_last
suba.l a6,a1
move.l a1,-(sp)
move.l a6,-(sp)
DOS _SETBLOCK
addq.l #8,sp
bsr system変数table作成
** ** ** ** ** **
.xdef restart
restart:
move.l MEM2,mem_last
clr.w EXITcode
bclr #warningF,d7
bclr #modeF,d7
* BASICのファイルを読み込む
lea.l basic_filename,a2
clr.w -(sp)
move.l a2,-(sp)
DOS _OPEN
tst.l d0
bge 1f
@@:
tst.b (a2)+
bne @b
move.b #'.',-1(a2)
move.b #'b',(a2)+
move.b #'a',(a2)+
move.b #'s',(a2)+
clr.b (a2)
DOS _OPEN
tst.l d0
bmi help
1:
move.l program_area,a5
move.l mem_last,d1
sub.l a5,d1
bcs mem_err
move.l d1,-(sp)
* move.l a5,-(sp)
pea.l 1(a5) * 行番号対策など
move.w d0,-(sp)
DOS _READ
lea.l 1(a5,d0.l),a2 * last address
clr.b (a2)
addq.l #1+1+3,d0
andi.b #$fc,d0
lea.l (a5,d0.l),a4
cmp.l d1,d0
bcc mem_err
DOS _CLOSE
lea.l 16(sp),sp
.ifdef _DEBUG
IOCS _ONTIME
move.l d0,d2
@@:
IOCS _ONTIME
cmp.l d0,d2
beq @b
lea.l _comptime(pc),a0
move.l d0,(a0)
.endif
* ベーシック内部で使用する変数の初期化
moveq #-1,d0 * 登録された個数 - 1
move.w d0,4+変数int
move.w d0,4+変数str
move.w d0,4+変数char
move.w d0,4+変数float
move.w d0,4+配列
move.w d0,8+中間言語行数
move.w d0,8+変数INIT
move.w d0,8+引数INIT
move.w d0,8+行番号
move.w d0,8+ラベル
move.w d0,8+goto飛先
movea.l nest_work,a0
clr.l (a0)+
clr.w 4+名前
bsr 内部関数
move.l a4,中間言語
move.l a4,$c+中間言語行数
.ifdef _DEBUG
moveq #$e,d1
IOCS _BITSNS
btst #0,d0
beq @f
bsr func情報
@@:
.endif
move.l program_area,a5
addq.l #1,a5
bset #no_cnfF,d7
bsr first_check_a5_in_line
tst.w d0
bne @f
bset #linenumF,d7 *行番号あり
@@:
move.b #$a,-(a5) * 行番号対策など
clr.l 行数
* グローバル関数ブロックの冒頭処理
* movem.l 変数INIT,d0/d1
* sub.l d1,d0
* move.w d0,(a4)+ * 変数 area を初期化する時の参照するオフセット
* movem.l 引数INIT,d0/d1
* sub.l d1,d0
* move.w d0,(a4)+ * 引き数を取り込む時、参照するオフセット
clr.l (a4)+ * 最初だから……
btst #b_argF,d7
beq @f
.xref b_argc_def
bsr b_argc_def
pea.l 引数INIT
moveq #1,d0 * 引き数の個数 - 1 ( b_argc;int , b_argv();str )
bsr buf書込 * d1.w/a0-a1 破壊
move.w #$8000,d0 * int
bsr buf書込
moveq #0,d0 * b_argc #
bsr buf書込
moveq #0,d0 * dim (1-dimensinal) + b_argv() #
bsr buf書込L
addq.l #4,sp
bra 1f
@@:
pea.l 引数INIT * 引き数何もなし
moveq #-1,d0 * 引き数の個数 - 1
bsr buf書込 * d1.w/a0-a1 破壊
addq.l #4,sp
1:
* コンパイラ・メインルーチンの始まり始まり
解釈ループ0:
.xdef break2
break2:
lea.l $100(a4),a0 * ちょっと余裕
cmpa.l mem_last,a0
bcc mem_err
* a5 から調べ始める。
* まず、空白(9,10,13,32)を飛ばして、先頭の文字を見る。
* '/'か(注釈の可能性大)、その他か(プログラムの本文か)
bsr first_check_a5
* 数字なら d0 = 0
* プログラム終了なら d0 = -1
* その他なら d0 = そのキャラクタ
tst.w d0
bmi end
beq bunpo_err
.ifdef _DEBUG
move.l 行数,d1
cmp.l break行数(pc),d1
bne @f
.xdef breaknum
breaknum:
nop * 指定した行数でブレイクチェックするための
@@:
.endif
cmpi.b #'}',d0
beq if_block
cmpi.b #'?',d0 * print省略形
bhi 文解釈
beq print省略形
cmpi.b #'*',d0
beq label_star
cmpi.b #'/',d0 * remark
bne 文解釈
cmpi.b #'*',1(a5)
bne 文解釈
bsr 行末まで飛ばし * 注釈だ
bra 解釈ループ0
print省略形:
addq.l #1,a5
moveq #5,d0 * 'print'$$$
bra stat22
label_star:
addq.l #1,a5
bsr hash
bsr @f
bra 解釈ループ
label_quote:
cmpi.b #'"',(a5)+
bne label_quote_err
bsr hash_label特別
bsr @f
cmpi.b #'"',(a5)+
bne label_quote_err
bra 解釈ループ
@@:
bsr label_sub * d0 = label #
move.l d0,d1
lsl.w #3,d1
addq.w #4,d1 * 行数の格納位置
movea.l 4+ラベル,a3
bsr bufgetL
addq.l #1,d0
bne ラベル二重定義
move.l a4,d2 * address
bsr bufputL
rts
ラベル二重定義:
ERRORS 81
label_quote_err:
ERROR 82
if_block:
addq.l #1,a5
ifb2:
movea.l nest_work,a0
tst.l (a0)
beq block_err
cmpi.w #3,8(a0)
bne block_err
move.w 10(a0),d0 * if_flag (0/1/2/3)
btst #0,d0 * block?
bne ifb1
bsr If_end * if 文で、改行終わりの時
bra ifb2 * もう一個上にある「はず」
ifb1:
btst #1,d0 * then/else
bne ifb3
bsr else_check
bne ifb3
addq.l #4,a5
movea.l nest_work,a0
clr.w 10(a0) * if_flag ( 0 = '{'のない/'}'で閉じた後の then ) (H8/2/1)
bsr Else
addq.l #1,a5 * ':' ごたごたしてるけど、とりあえず
bra 解釈ループ0 * すぐ文
ifb3:
bsr If_end * if 文で、ブロック終わりの時
bra 解釈ループ
block_err:
ERROR 31
文解釈:
* 最初の対象を見つけたので
* これからハッシュ値を計算しながら、文字数を数えさせる
bsr hash
* a2.l = 元の対象の開始アドレス
* d5.w = ハッシュ値だ。上位バイトもそのままだ
* d4.l = (hash.w)(文字数-1)
* d1.b = お次の文字 ( (,[,=,:, , etc... )
tst.w d4
bmi bunpo_err
* 対象がどれかステートメントと一致するかどうか
* a2.l = 元の対象の開始アドレス
* d5.w = ハッシュ値
* d4.w = 文字数 - 1
bsr statement_check
* 一致すれば d0 = そのステートメント番号
* 一致しなければ d0 = 0
stat22:
tst.w d0
beq ステートメントでない
cmpi.w #$2a,d0 * 'label'
beq label_quote
* 各ステートメントごとに文法が違うのでいちいち異なる解釈をしなければ
* d1.b = お次の文字 ( (,[,=,:, , etc... )
bsr stat解釈
bra 解釈ループ
ステートメントでない:
* 関数かどうかチェックする
cmpi.b #'(',d1
bne 変数かどうかチェック
* d4.l = * (hash.w)(文字数-1)
* a2.l = 元の対象の開始アドレス
bsr function_check
* d0.w = ヒットした関数の返り値の型 ( = 0 : 該当関数無し )
* = $8000 float
* = $8001 int
* = $8003 str
* = $ffff void
* d0.w < 0 の時
* d1.w = 引き数の個数
* d3.w = 0 から始まる関数番号 ( < 0 : 内部関数になる予定 )
* a2 = パラメーターテーブル
tst.w d0
beq 変数かどうかチェック
* 関数の処理
clr.w (a4)+ * 中間言語書き込み
movea.l a4,a3
* 関数の解釈
* input a2 = パラメーターテーブル
* a3 = 書き込み先アドレス
* d1.w = 引き数の個数
* d3.w = 0 から始まる関数番号 ( < 0 : 内部関数になる予定 )
bsr function解釈
* d0 = 書き込んだ長さ
add.l d0,a4
bra 解釈ループ
変数かどうかチェック:
* d4.l = * (hash.w)(文字数-1)
* a2.l = 元の対象の開始アドレス
bsr variable_check
* 重なってない d2.l = -1
* int の n 番と一致 d2.l = n+0000 ( n < システム変数 )
* str の n 番と一致 d2.l = n+0100 ( n < システム変数 )
* char の n 番と一致 d2.l = n+0200
* float の n 番と一致 d2.l = n+8000
* d2.l < 0 = 代入出来ない(当たりがない or system 変数)
* d0 = 0 : 普通の変数
* 1 : 配列 ( a0 = その配列情報のポインタ , d1 = 添え字の最大数 )
* $80 : auto 変数
* $81 : auto 配列 ( a0 = その配列情報のポインタ , d1 = 添え字の最大数 )
* -1 : 当たりなし
bmi misengen
tst.l d2
bmi sysに代入
bclr #7,d0
beq @f
swap d2
not.w d2 * AUTO 変数
swap d2
@@:
tst.w d0
beq 配列以外に代入
* beq 普通の変数に代入
* 配列に代入
cmpi.b #'(',(a5)
bne dim_init
move.l d2,-(sp) * 式の型・保存
moveq #0,d0 * 添え字書き込みサイズ
move.w $a(a0),d1 * 次元 - 1
lea.l tmp,a3
@@:
addq.l #1,a5
movem.l d0/d1,-(sp)
moveq #0,d2 * 添え字は整数だ
* 解釈した結果を (a3) からに書き込み、その長さを d0.l に返す
* int d2.w = 0000
bsr math解釈
add.l (sp)+,d0
move.l (sp)+,d1
cmpi.b #',',(a5)
dbne d1,@b
beq 添え字の個数が多い
tst.w d1
bne 添え字の個数が少ない
cmpi.b #')',(a5)+
bne bunpo_err
move.l (sp)+,d2
bra 普通の変数に代入
sysに代入:
swap d2
addq.w #1,d2
beq set_date
addq.w #2,d2
beq set_time
ERRORS 58 * date$, time$ 以外に代入
set_date:
clr.w -(sp)
bra @f
set_time:
move.w #1,-(sp)
@@:
move.w #41*2,(a4)+ * statement $$$ 'SysVar'
swap d2 * d2.w = $0100
bsr first_check_a5_in_line *
cmpi.b #'=',(a5)+
bne bunpo_err
movea.l a4,a3
* 解釈した結果を (a3) からに書き込み、その長さを d0.l に返す
* str d2.w = 0100
bsr math解釈
movea.l a3,a4
move.w (sp)+,(a4)+
bra 解釈ループ
配列以外に代入:
cmpi.b #'[',(a5)
beq 文字列の途中への代入
普通の変数に代入:
move.l d0,-(sp) * 普通の変数になら 0.w
* 配列,a[i] になら今 tmp 上にある添え字式の長さ ( >0 )
bsr first_check_a5_in_line *
cmpi.b #'=',(a5)+
bne bunpo_err
* movea.l a4,a3
lea.l 2(a4),a3
* 解釈した結果を (a3) からに書き込み、その長さを d0.l に返す
* int d2.w = 0000
* str d2.w = 0100
* char d2.w = 0200
* float d2.w = 8000
* 型未判明 d2.w = ffff
bsr math解釈
* return d6.w = 変数の型(d2=ffff 以外なら d2.l を保存)
lsr.w #8,d6
bset #15,d6 * 代入式の印、下位バイトは変数の型
move.l (sp)+,d1
tst.w d1 * あやしいから
beq 普通変数代入用中間言語
* 配列代入用中間言語
bset #14,d6 * 配列の印
move.w d6,(a4)+ * 中間言語書き込み
add.l d0,a4
swap d6 * 配列番号
move.w d6,(a4)+ * 中間言語書き込み
lsr.w #1,d1
subq.w #1,d1
bcs sonnahazuhanai
lea.l tmp,a0 * 添え字の式
@@:
move.w (a0)+,(a4)+
dbra d1,@b
bra 解釈ループ
普通変数代入用中間言語:
move.w d6,(a4)+ * 中間言語書き込み
add.l d0,a4
swap d6 * 変数番号
move.w d6,(a4)+ * 中間言語書き込み
bra 解釈ループ
文字列の途中への代入:
* 文字列の途中 a[i]への代入
move.w #38*2,(a4)+ * statement $$$ 'STR'
move.l d2,-(sp)
addq.l #1,a5
moveq #0,d2 * 添え字は整数だ
movea.l a4,a3
* 解釈した結果を (a3) からに書き込み、その長さを d0.l に返す
* int d2.w = 0000
bsr math解釈
cmpi.b #']',(a5)+
bne bunpo_err
bsr first_check_a5_in_line
cmpi.b #'=',(a5)+
bne bunpo_err
move.w #$0200,d2 * char 型。
* 解釈した結果を (a3) からに書き込み、その長さを d0.l に返す
* char d2.w = 0200
* 型未判明 d2.w = ffff
bsr math解釈
* return d6.w = 変数の型(d2=ffff 以外なら d2.l を保存)
movea.l a3,a4
move.l (sp)+,d2 * 上位ワードは文字列変数番号
swap d2 * 変数番号
move.w d2,(a4)+ * 中間言語書き込み
bra 解釈ループ
dim_init:
bsr first_check_a5_in_line
cmpi.b #'=',d0
bne bunpo_err
lea.l $a(a0),a0
move.w (a0)+,d3
moveq #1,d0
moveq #0,d1
@@:
move.w (a0)+,d1
addq.l #1,d1
FPACK __UMUL
dbra d3,@b
move.l d0,d1
* 初期化データ
* d3 = 型
* d2 = 配列番号
* d1 = 添え字大きさ
move.w d2,d3
lsr.w #8,d3
swap d2
bsr dim_init_data
*bra 解釈ループ
解釈ループ:
bsr first_check_a5_in_line
bmi 解釈ループ0 * 改行文字だ
cmpi.b #':',d0
beq コロン
cmpi.b #'}',d0 * 'if' block end
beq 解釈ループ0
cmpi.b #'/',d0 * 注釈
bne @f
cmpi.b #'*',1(a5)
beq 解釈ループ0
@@:
bsr else_check * else の可能性あり
bne bunpo_err
bra 解釈ループ0
コロン:
addq.l #1,a5
bra 解釈ループ0
* 未宣言変数への代入があれば、警告を出して整数型に勝手に宣言する
未宣言をint:
bsr 未宣言をint_sub
moveq #0,d0 * 普通の変数に代入につなぐため必要
bra 普通の変数に代入
.xdef misengen
misengen:
cmpi.b #'=',(a5)
beq 未宣言をint
cmpi.b #'(',(a5)
bne misengen_var
ERRORS 34
bunpo_err:
ERROR 4
misengen_var:
ERRORS 7
sonnahazuhanai:
ERROR 2
添え字の個数が少ない:
ERROR 56
添え字の個数が多い:
ERROR 57
* メイン・関数ブロック終了時の処理
end:
tst.b d7 * global/auto
bmi 内部関数あり
* global
movea.l nest_work,a0
tst.l (a0)
bne nest_structure終わってない
move.w #$0013*2,(a4)+ * 'end'$$$
bsr global変数リスト作成
bra @f
内部関数あり:
bclr #endfuncF,d7
beq no_endfunc
@@:
move.l a4,変数area
.xref Goto整理
bsr Goto整理
* 中間言語にコンパイルするのが終わった
* 変数・引数INIT が連結でなかったら、つなぐ
lea.l 変数INIT,a1
bsr chain連結
lea.l 引数INIT,a1
bsr chain連結
.ifdef _DEBUG
bsr DEBUG情報
.endif
btst #warningF,d7
beq @f
pea.l _warning発生(pc)
bsr YorN
addq.l #4,sp
beq @f
move.w #1,EXITcode
bra endendend
@@:
moveq #Finit,d1
bsr Fルーチン
moveq #Frun,d1
bsr Fルーチン
bset #0,global_flag * Finit通った
clr.l 行数
bclr #modeF,d7 * global mode
.ifndef _DEBUG
bset #cursorF,d7 * cursor ON
move.w #18,-(sp) * cursor OFF
DOS _CONCTRL
addq.l #2,sp
.endif
clr.w scroll開始行
bsr FKEYset
; 実行時間の表示(開始時間) by Eriko 95/02/19
.ifdef _RUNTIME
IOCS _ONTIME
move.l d0,d2
@@
IOCS _ONTIME
cmp.l d0,d2
beq @b
lea.l _runtime(pc),a0
move.l d0,(a0)
.endif ここまで
btst #b_argF,d7
beq @f
move.l b_argv,-(sp)
subq.l #4,sp
move.w #$0003,-(sp) * str (関係ないけど一応)
move.l b_argc,-(sp)
subq.l #4,sp
move.w #$0001,-(sp) * int (関係ないけど一応)
move.w #2,-(sp) * 2個
@@:
move.l 中間言語,a5
bsr basic_exec
.xdef endendend
endendend:
; 実行時間の表示 by Eriko 95/01/27
.ifdef _RUNTIME
IOCS _ONTIME
sub.l _runtime(pc),d0
lea.l tmp,a0
move.l a0,-(sp)
moveq #6,d1
FPACK __IUSING
move.l #'/100',(a0)+
move.w #$0d0a,(a0)+
clr.b (a0)
DOS _PRINT
addq.l #4,sp
.endif ここまで
moveq #0,d3 * EXITcode 予約
movea.l a6保存(pc),a6
move.l a6,d0
bmi exit
movea.l SPinit,sp
tst.w tagFP
bmi @f
move.w tagFP,-(sp)
DOS _CLOSE
addq.l #2,sp
move.w #-1,tagFP
@@:
bsr FKEY戻す
move.w #17,-(sp) * cursor on
DOS _CONCTRL
addq.l #2,sp
tst.w EXITcode
beq @f
tst.b ed_filename
beq @f
bsr ed起動
bne restart
@@:
move.l _breakflag+2(pc),-(sp)
beq @f
move.w #$2d,-(sp) * CTRL+C によるブレークチェックフラグのセット
DOS _INTVCS
@@:
move.l #$0006_00ff,(sp)
DOS _KFLUSH
move.w breakcheck,(sp)
bmi @f
DOS _BREAKCK
@@:
btst #0,global_flag
beq @f
moveq #Fend,d1
bsr Fルーチン
moveq #Fexit,d1
bsr Fルーチン
@@:
moveq #0,d0
bsr 初期化sub
move.w EXITcode,d3
move.l a6,-(sp)
DOS _MFREE
addq.l #4,sp
exit:
bsr 最左カラム
move.w d3,-(sp)
DOS _EXIT2
help:
pea.l _TITLE(pc)
DOS _PRINT
pea.l _HELP(pc)
DOS _PRINT
move.w #1,(sp)
DOS _EXIT2
初期化sub:
lea.l sinitASK,a0
move.b sinitFLAG,d3
bne @f
addq.l #1,a0
@@:
tst.b (a0)
bgt 初期化しない
bmi @f
tst.w d0
bne @f
pea.l _初期化するか(pc)
bsr YorN
addq.l #4,sp
bne 初期化しない
@@:
add.b d3,d3 bit 7:screen/console/width 64
bcc @f
move.l #$0010_0000,-(sp)
DOS _CONCTRL
* move.w #$000e,(sp)
subq.w #2,(sp)
DOS _CONCTRL
pea.l _TITLE(pc)
DOS _PRINT
addq.l #8,sp
@@:
add.b d3,d3 bit 6:color []
bcc @f
bsr init_tpal
@@:
初期化しない:
rts
mem_err0:
pea.l 1+errmes(pc)
DOS _PRINT
move.w #1,(sp)
DOS _EXIT2
mem_err1:
move.w #-1,関数file数
ERROR 0
mem_err:
ERROR 1
nest_structure終わってない:
ERROR 42
no_endfunc:
ERROR 43
.ifdef _DEBUG
filename:
.dc.b 'test.obj',0
filename2:
.dc.b 'test.var',0
.endif
xbcnf_file:
.dc.b 'xb.cnf',0
cnf_file:
.dc.b 'basic.cnf',0
_TITLE:
.dc.b $1b,'[1m ぺけBASIC',$1b,'[m ver.0.02 ( H9/3/5 版 ) (c)v914AKSTN.',13,10,0
_HELP:
* .dc.b 'とりあえずベーシックのファイル名を指定して実験',13,10
.dc.b '使用方 : xb.r [-option] BASICファイル名(.bas)',13,10
.dc.b 9,'-f<数字> : フリーエリアの大きさの指定 ( Kb 単位 )',13,10
.dc.b 9,'-c<名前> : コンフィグファイル名の指定',13,10
.dc.b 9,'-e<文字> : 拡張機能の ON/OFF',13,10
.ifdef _DEBUG
.dc.b 9,'-d<行数> : 指定行にて breaknum のブレイクチェック',13,10
.dc.b ' * DEBUG MODE *',13,10,0
M01: .dc.b '確保メモリ:',0
M02: .dc.b '残りメモリ:',0
Mkb: .dc.b ' Kb',13,10,0
.endif
.dc.b 0
.even
_BREAK: * CTRL+C によるブレークチェックフラグのセット
move.l a0,-(sp)
* キーバッファに無理矢理改行を書き込む(いいのか?)
cmpi.w #$40,$812.w
beq 1f
movea.l $814.w,a0
addq.l #2,a0
cmpa.w #$89c,a0
bcs @f
lea.l $81c.w,a0
@@:
move.w #$1d0d,(a0)
move.l a0,$814.w
addq.w #1,$812.w
1:
lea.l _breakflag(pc),a0
move.w #-1,(a0) * ブレークチェックフラグのセット
move.l (sp),a0
move.l _breakflag+2(pc),(sp) * 元のベクタアドレス
rts
.xdef _breakflag
_breakflag:
.dc.w 0
.dc.l 0
a6保存:
.dc.l 0
.ifdef _RUNTIME
_runtime:
.dc.l 0
.endif
.ifdef _DEBUG
_comptime:
.dc.l 0
.endif
** ** ** ** ** ** ** ** ** **
.xdef errors
.xdef error
.xdef warnings
.xdef warning
errors:
bsr 最左カラム
bsr err画面
bsr errors_sub
bra @f
error:
bsr 最左カラム
bsr err画面
bsr error_sub
@@:
move.w #1,EXITcode
bra endendend
warnings:
btst #warnoffF,d7
bne warnend
movem.l d0-d2/d4/a0-a4,-(sp)
pea.l _warning(pc)
DOS _PRINT
addq.l #4,sp
move.l (sp),d0 * error #
bsr errors_sub
bra @f
warning:
btst #warnoffF,d7
bne warnend
movem.l d0-d2/d4/a0-a4,-(sp)
pea.l _warning(pc)
DOS _PRINT
addq.l #4,sp
move.l (sp),d0 * error #
bsr error_sub
@@:
movem.l (sp)+,d0-d2/d4/a0-a4
bset #warningF,d7
warnend:
rts
err画面:
move.l d0,-(sp)
moveq #1,d0
bsr 初期化sub
move.w #$0101,sinitASK
move.l (sp)+,d0
rts
errors_sub:
move.w d0,-(sp)
lea.l tmp,a0
move.l a0,-(sp)
move.b #$27,(a0)+
@@:
move.b (a2)+,(a0)+
dbra d4,@b
move.b #$27,(a0)+
move.b #' ',(a0)+
clr.b (a0)
DOS _PRINT
addq.l #4,sp
move.w (sp)+,d0
bra 1f
error_sub:
clr.b tmp
1:
lea.l errmes(pc),a1
@@:
tst.b (a1)+
bne @b
dbra d0,@b
move.l a1,-(sp) * error message
DOS _PRINT
addq.l #4,sp
lea.l $100+tmp,a0 * tag file に書き出す文字列
move.b #$09,(a0)+
move.l 行数,d1
beq 3f
pea.l tenten(pc)
DOS _PRINT
move.l d1,(sp) * 行数表示
bsr dec_print
pea.l gyou(pc)
DOS _PRINT
addq.l #8,sp
move.l d1,d0 * tag file
moveq #6,d1
FPACK __IUSING
move.b #' ',(a0)+
move.b #':',(a0)+
move.b #' ',(a0)+
lea.l tmp,a2 * 変数名などの情報
@@:
move.b (a2)+,(a0)+
bne @b
subq.l #1,a0
bra 4f
3:
clr.b ed_filename * 行数の情報がないエラーならエディタは起動しない
4:
pea.l crlf(pc)
DOS _PRINT
addq.l #4,sp
@@:
move.b (a1)+,(a0)+ * error message を tag file に
bne @b
move.b #$0d,-1(a0)
move.b #$0a,(a0)+
clr.b (a0)
tst.b tag_filename * tag file 書きだし
beq 1f
move.w tagFP,d0
bge @f
move.w #$20,-(sp)
pea.l tag_filename
DOS _CREATE
addq.l #6,sp
move.w d0,tagFP
@@:
move.w d0,-(sp)
pea.l basic_filename
DOS _FPUTS
addq.l #4,sp
pea.l $100+tmp
DOS _FPUTS
addq.l #6,sp
1:
rts
.xdef YorN
YorN:
move.l 4(sp),-(sp)
DOS _PRINT
pea.l _YorN(pc)
DOS _PRINT
addq.l #8,sp
DOS _GETCHAR
move.w d0,-(sp)
pea.l crlf(pc)
DOS _PRINT
addq.l #4,sp
moveq #$20,d0
or.w (sp)+,d0
cmpi.b #'y',d0
rts
_YorN:
.dc.b ' ( Y or N )',0
_warning発生:
.dc.b 'ワーニングがありますが、プログラムを実行しますか?',0
_初期化するか:
.dc.b '画面を初期化しますか?',0
_warning:
.dc.b 'Warning : ',0
tenten:
.dc.b ' ……',0
gyou:
.dc.b '行目',0
crlf:
.dc.b 13,10,0
errmes: .dc.b 0
e00: .dc.b 'メモリを確保出来ませんでした',13,10,0
e01: .dc.b 'フリーエリアが足りませんです',0
e02: .dc.b 'ぺけBにバグ有り',0
e03: .dc.b 'そのステートメントは未サポートだ',0
e04: .dc.b '文法エラー',0
e05: .dc.b '変数の宣言が変である',0
e06: .dc.b '二重に宣言するなんて',0
e07: .dc.b 'そいつは未宣言の変数だろう',0
e08: .dc.b 'スタックがあふれました',0
e09: .dc.b '変な式だな',0
e10: .dc.b 'そのステートメントはまだ実行出来ない',0
e11: .dc.b 'dim 無しで配列宣言しましたね',0
e12: .dc.b '行番号がここだけないです',0
e13: .dc.b '先頭が数字だとややこしいですよ',0
e14: .dc.b 'コンフィグの書き方が変である',0
e15: .dc.b '指定された外部関数のファイルが無い',0
e16: .dc.b '関数の引き数が多いみたいだが',0
e17: .dc.b 0 *'配列はもうちょっと待つんだ',0
e18: .dc.b '関数の中に変な引き数があるな',0
e19: .dc.b '外部関数ファイルのパラメータテーブルがおかしい',0
e20: .dc.b '外部関数内でエラーだわ',0
e21: .dc.b 'void 型の関数には返り値はないんだよ',0
e22: .dc.b 'ステートメントのパラメータの個数が少ない',0
e23: .dc.b 'color[ に対応する ] がありません',0
e24: .dc.b 'width に指定出来る値は 64 と 96 だけです',0
e25: .dc.b 'for 文の書き方がおかしい',0
e26: .dc.b '使用する変数の型が違う',0
e27: .dc.b 'next に対応する for がない',0
e28: .dc.b 'ネスト構造無しに break, continue はできません',0
e29: .dc.b 'if のない then, else です',0
e30: .dc.b 'if 文の書き方がおかしい',0
e31: .dc.b '式の型が違う',0
e32: .dc.b 'endwhile に対応する while がない',0
e33: .dc.b 'until に対応する repeat がない',0
e34: .dc.b '未宣言の関数か配列でないかい',0
e35: .dc.b '配列の宣言に添え字の指定がありませんよ',0
e36: .dc.b '配列の宣言がおかしいですよ',0
e37: .dc.b '配列の添え字が大きすぎます',0
e38: .dc.b '配列の添え字が負の数のようですね',0
e39: .dc.b 'func 文の書式に間違いがあるです',0
e40: .dc.b 'その関数名はすでに使われております',0
e41: .dc.b '文字列へアクセスするポインタの値がまずいです',0
e42: .dc.b 'ネスト構造が閉じていませんね',0
e43: .dc.b 'endfunc がありませんです',0
e44: .dc.b 'locate のパラメータが無効ですねん',0
e45: .dc.b 'endfunc or return に対応する func がありませんです',0
e46: .dc.b 'switch の中で continue ですか?',0
e47: .dc.b 'case, default, endswitch には switch が必要なんです',0
e48: .dc.b 'switch にはやっぱり 1 個は case がないと',0
e49: .dc.b 'func ~ endfunc の中に返り値がありません',0
e50: .dc.b 'return 文の書き方変',0
e51: .dc.b 'using 文のフォーマットがおかしい',0
e52: .dc.b 'using 文の後の ',$27,';',$27,' がないです',0
e53: .dc.b 'console文のパラメータがまずい',0
e54: .dc.b 'break しました',0
e55: .dc.b 'input, linput 文の書き方違う',0
e56: .dc.b '配列の添え字の個数が少ないんです',0
e57: .dc.b '配列の添え字の個数が多いんです',0
e58: .dc.b 'システム変数にゃ代入出来ません',0
e59: .dc.b '未宣言変数を int 型に割り振ります',0
e60: .dc.b '配列は10次元までしか扱えないんですゴメンナサイ',0
e61: .dc.b 'default の後に case, default は置かない方がいいですよね',0
e62: .dc.b 'exit 文の書き方変である',0
e63: .dc.b 'key に , がありませんね',0
e64: .dc.b 'key のパラメーターがまずいです',0
e65: .dc.b '指定されたコンフィグファイルがありません',0
e66: .dc.b '行番号の後には空白をお願いします',0
e67: .dc.b 'input系, key があるので、ファンクションキーを本家互換に書き替えた方がいいです',0
e68: .dc.b 'エディタを起動出来ません',0
e69: .dc.b '0で割ること出来ません',0
e70: .dc.b 'date$, time$ へ変な値を代入しないで下さい',0
e71: .dc.b 'screen の画面モードが異常です',0
e72: .dc.b 'GV-RAM は使用中です',0
e73: .dc.b 'console の3番目の引数が規定の範囲を超えています',0
e74: .dc.b '関数の引き数の配列の添字が合いませんのぉ',0
e75: .dc.b '引き数の配列の次元が合いません',0
e76: .dc.b 'end がありません',0
e77: .dc.b '引き数に配列なんか使えません',0
e78: .dc.b '指定の行番号はありません',0
e79: .dc.b '使える行番号は 0 から 65535 までなんです',0
e80: .dc.b '変な goto',0
e81: .dc.b 'そのラベル名はすでに使用されてます',0
e82: .dc.b 'label はちゃんと " でくくってください',0
e83: .dc.b 'goto で関数ブロックの外に飛びだしちゃいけません',0
e84: .dc.b '配列の添字の大きさには定数しか使えません',0
e85: .dc.b 'global な可変長配列は使えません',0
.even
* エディタを起動して、タイムスタンプが変わっていたら再実行
ed起動:
move.w #$23,-(sp)
pea.l basic_filename
pea.l tmp
DOS _FILES
lea.l 10(sp),sp
bmi ed起動end
move.l 22+tmp,-(sp)
lea.l tmp,a0
lea.l ed_filename,a1
@@:
move.b (a1)+,(a0)+
bne @b
move.b #' ',-1(a0)
lea.l tag_filename,a1
@@:
move.b (a1)+,(a0)+
bne @b
movem.l d0-d7/a0-a6,-(sp)
clr.l -(sp)
pea.l $100+tmp
pea.l tmp
move.w #2,-(sp)
DOS _EXEC
tst.l d0
bmi ed起動err
clr.w (sp)
DOS _EXEC
lea.l 14(sp),sp
movem.l (sp)+,d0-d7/a0-a6
move.w #$23,-(sp)
pea.l basic_filename
pea.l tmp
DOS _FILES
lea.l 10(sp),sp
move.l (sp)+,d0
cmp.l 22+tmp,d0
rts
ed起動end:
moveq #-1,d0
rts
ed起動err:
clr.l 行数
ERROR 68
* basic.cnf を読み込んで評価する。
* 今のところ " FUNC = " 行のみ有効
* d5.w = 関数ファイルの個数
cnf_read:
lea.l -$4000(sp),sp * tmp
movea.l sp,a5
lea.l _SP上限(a6),a3
* .cnf 読み込み
lea.l cnf_filename,a2
tst.b (a2)
beq 1f
lea.l tmp,a0
bsr cnf_sub0
bge @f
ERROR 65
1:
lea.l xbcnf_file(pc),a2
bsr cnf_sub
bge @f
lea.l cnf_file(pc),a2
bsr cnf_sub
bmi help
@@:
moveq #0,d5 * 関数ファイルの個数
moveq #1,d0
move.l d0,行数
cr_loop:
bsr first_check_a5
* 数字なら d0 = 0
* ファイル終了なら d0 = -1
* その他なら d0 = そのキャラクタ
tst.w d0
beq cf_err
bmi cf_end
cmpi.b #'*',d0
beq cnf_cont
lea.l _cnfS(pc),a2 * config の命令 list
bsr fc_check_sub
* d6 = 命令番号*2 (-1=該当無い)
bmi cf_err
bsr first_check_a5
cmpi.b #'=',(a5)+
bne cf_err
bsr first_check_a5
tst.w d0
bmi cf_err
move.w cc(pc,d6.w),d6
jmp cc(pc,d6.w)
cc:
.dc.w Func-cc
.dc.w Beep-cc
.dc.w Caps-cc
.dc.w Free-cc
.dc.w Width-cc
.dc.w Fkey-cc
.dc.w Warn-cc
.dc.w Sinit-cc
.dc.w Tag-cc
.dc.w EdEd-cc
.dc.w Extend-cc
_cnfS:
.dc.b 'func',0
.dc.b 'beep',0
.dc.b 'caps',0
.dc.b 'free',0
.dc.b 'width',0
.dc.b 'fkey',0
.dc.b 'warn',0
.dc.b 'sinit',0
.dc.b 'tag',0
.dc.b 'ed',0
.dc.b 'extend',0
.dc.b 0
_cnfT:
.dc.b 'on',0 * 0
.dc.b 'off',0
.dc.b 'always',0 * 4
.dc.b 'ask',0
.dc.b 'never',0
.dc.b 'auto',0 * 10
.dc.b 0
.even
Free:
movea.l a5,a0
FPACK __STOL
movea.l a0,a5
tst.w _FREEMEM(a6)
bne cnf_cont
move.w d0,_FREEMEM(a6)
bra cnf_cont
Beep:
Caps:
Width:
bra cnf_cont
Sinit:
lea.l sinitASK,a1
moveq #2-1,d2
@@:
bsr first_check_a5_in_line
bsr fc_check_subT
subq.w #4,d6
bcs cf_err
cmpi.w #6,d6
bcc cf_err
subq.w #2,d6
move.b d6,(a1)+
dbra d2,@b
bra cnf_cont
Fkey:
moveq #fnckeyF,d2
bsr fc_check_subT
beq FkeyOn
subq.w #2,d6 * off
beq FkeyOff
subq.w #8,d6 * auto
bne cf_err
bset #fncautoF,d7
FkeyOff:
bset d2,d7
bra cnf_cont
FkeyOn:
bclr d2,d7
bra cnf_cont
Warn:
moveq #warnoffF,d2
bsr fc_check_subT
beq WarnOn
subq.w #2,d6
bne cf_err
WarnOff:
bset d2,d7
bra cnf_cont
WarnOn:
bclr d2,d7
bra cnf_cont
EdEd:
lea.l ed_filename,a0
bra @f
Tag:
lea.l tag_filename,a0
@@:
move.b (a5)+,d0
cmpi.b #$20,d0
bcs @f
move.b d0,(a0)+
bra @b
@@:
clr.b (a0)+
subq.l #1,a5
bra cnf_cont
Extend:
clr.w d0
move.b (a5)+,d0
cmpi.b #$20,d0
bcs @f
ori.b #$20,d0
subi.b #'a',d0
bcs cf_err
cmpi.b #'z'-'a',d0
bhi cf_err
move.b _ext_flag(pc,d0.w),d0
beq cf_err
bset d0,d7
bra Extend
@@:
subq.l #1,a5
bra cnf_cont
_ext_flag:
.dc.b b_argF * a
.dc.b 0,breakoffF,fnc_dimF,len_dimF,0 * b,c,d,e
.dc.b 0,0,v_initF,0,0 * g,h,i
.dc.b labelF,0,0,0,0 * l
.dc.b 0,0,0,0,0
.dc.b 0,0,0,0,0
Func:
addq.l #1,d5 * 関数ファイルの個数 ++
@@:
move.b (a5)+,d0
cmpi.b #$20,d0
bcs @f
move.b d0,(a3)+
bra @b
@@:
clr.b (a3)+
subq.l #1,a5
* bra cnf_cont
cnf_cont:
bsr 行末まで飛ばし
bra cr_loop
cf_end:
subq.w #1,d5 * 関数ファイルの個数 - 1
move.w d5,関数file数
tst.b ed_filename
beq 1f
lea.l tag_filename,a0
tst.b (a0)
bne 1f
lea.l _tag(pc),a1
@@:
move.b (a1)+,(a0)+
bne @b
1:
lea.l $4000(sp),sp
rts
cf_err:
clr.b basic_filename
clr.b ed_filename
ERROR 14
_tag: .dc.b 'xb.err',0
.even
* .cnf の読み込み
cnf_sub:
lea.l tmp,a0
lea.l 起動dir,a1
@@:
move.b (a1)+,(a0)+
bne @b
subq.l #1,a0
cnf_sub0:
move.b (a2)+,(a0)+
bne cnf_sub0
clr.w -(sp)
pea.l tmp
DOS _OPEN
addq.l #6,sp
tst.l d0
bmi cnf_ret
move.l #$4000-1,-(sp) * .cnf size の上限 $4000-1 (問題ないでしょう)
move.l a5,-(sp)
move.w d0,-(sp)
DOS _READ
clr.b (a5,d0.l)
DOS _CLOSE
lea.l 10(sp),sp
moveq #0,d0
cnf_ret:
rts
fc_check_subT:
lea.l _cnfT(pc),a2
fc_check_sub:
moveq #0,d6
fc_check2:
tst.b (a2)
beq fc_checkend
movea.l a5,a0
@@:
move.b (a2)+,d0
beq fc_ok
moveq #$20,d1
or.b (a0)+,d1
cmp.b d1,d0
beq @b
@@:
tst.b (a2)+ * 次へ
bne @b
addq.w #2,d6
bra fc_check2
fc_ok:
moveq #$20,d1
or.b (a0),d1 * 英字以外でないと
cmpi.b #'a',d1
bcs @f
cmpi.b #'z',d1
bcs fc_checkend
@@:
movea.l a0,a5
tst.w d6 * 0 以上
rts
fc_checkend:
moveq #-1,d6
rts
func_read:
move.w 関数file数,d5
move.l a4,関数list
movea.l a4,a3 * 関数ファイルのリスト
move.w d5,d0
bmi fnc_整理整頓
lsl.w #2,d0
lea.l 4(a4,d0.w),a4 * + 4+4*(関数の個数 - 1)
lea.l _SP上限(a6),a2
fr_loop:
lea.l tmp,a0 * '=' の後ろ
.ifndef _DEBUG * _DEBUG が定義されてなければ
lea.l 起動dir,a1 * 起動ディレクトリから探す
@@:
move.b (a1)+,(a0)+
bne @b
subq.l #1,a0
.endif
@@:
move.b (a2)+,(a0)+
bne @b
move.b #'.',-1(a0)
move.b #'f',(a0)+
move.b #'n',(a0)+
move.b #'c',(a0)+
clr.b (a0)
.ifdef _DEBUG * _DEBUG が定義されてると
clr.l -(sp) * PATH の通ったディレクトリから探す
pea.l $100+tmp
pea.l tmp
move.w #2,-(sp)
DOS _EXEC
lea.l 14(sp),sp
tst.l d0
bmi fnc_err
.endif
move.l mem_last,-(sp) * limit address
move.l a4,-(sp)
pea.l tmp
move.b #3,(sp) * X 形式のファイルとして読み込み
move.w #3,-(sp)
DOS _EXEC
lea.l 14(sp),sp
tst.l d0
ble fnc_err
* 登録
move.l a4,(a3)+
* addq.l #3,d0
* andi.b #$fc,d0 * あんまり関係ないからいらない?
adda.l d0,a4
dbra d5,fr_loop
fnc_整理整頓:
* 読み込みが終了したので、外部関数の整理整頓をする。
moveq #-1,d6 * 関数の個数 - 1
movea.l 関数list,a3
move.l a4,関数buf
lea.l _SP上限(a6),a4
.xref standard_init
bsr standard_init
move.w 関数file数,d5
bmi fnc_end2
func_init_loop:
movea.l (a3)+,a0
move.l Ftokun(a0),a5
movem.l Fpara(a0),a0-a1
* a5 = トークン テーブルの先頭アドレス
* a0 = パラメータ
* a1 = 実行アドレス
move.w d5,-(sp)
bsr func_hash
move.w (sp)+,d5
dbra d5,func_init_loop
fnc_end2:
movea.l 関数buf,a4
move.w d6,関数個数
lea.l _SP上限(a6),a3 * とりあえず作った関数テーブル
lea.l 外部functable,a5 * 本物の関数テーブルを格納
bsr func_sort
rts
fnc_err:
move.w #-1,関数file数
cmpi.w #$fff8,d0 * メモリが足りない
beq mem_err
ERROR 15
* a3 から始まる (d6+1) 個のハッシュ値付きのテーブルを a4 に並べ直す。
* a5 に参照用テーブルを作る
func_sort:
move.w d6,d4
addq.w #1,d4
lsl.w #2,d4
suba.w d4,sp
movea.l sp,a0
move.w d6,d0
@@:
move.l a3,(a0)+
lea.l $10(a3),a3
dbra d0,@b
move.w d6,d2
subq.w #1,d2
bmi fs_loop_end
lea.l 4(sp),a3
fs_loop:
movea.l (a3),a0
move.b 1(a0),d0
move.w d6,d5
sub.w d2,d5
subq.w #1,d5
movea.l a3,a2
@@:
movea.l -(a2),a1
cmp.b 1(a1),d0 * hash の下1バイト
bcc @f
move.l a1,4(a2)
dbra d5,@b
subq.l #4,a2
@@:
move.l a0,4(a2)
addq.l #4,a3
dbra d2,fs_loop
fs_loop_end:
moveq #0,d0
moveq #-1,d1
moveq #0,d2
movea.l sp,a1
clr.w (a5)+ * 関数buf からのオフセット
fs_2:
movea.l (a1)+,a0
@@:
cmp.b 1(a0),d0
beq fs_1
move.w d1,(a5)+ * 個数
move.w d2,(a5)+ * 関数buf からのオフセット
addq.b #1,d0
moveq #-1,d1
bra @b
fs_1:
move.l (a0)+,(a4)+
move.l (a0)+,(a4)+
move.l (a0)+,(a4)+
move.l (a0)+,(a4)+
addq.w #1,d1
add.w #$10,d2
dbra d6,fs_2
move.w d1,(a5)+ * 個数
move.w #$100-2,d1
sub.w d0,d1
bmi fs_3
moveq #-1,d0
@@:
move.l d0,(a5)+ * 残りを埋める
dbra d1,@b
fs_3:
adda.w d4,sp
rts
* (a5) から始まるトークンリストからハッシュ値を計算してテーブルを作る
func_hash:
tst.b (a5)
beq fi_loop1_end
fi_loop1:
bsr hash
* a2.l = 元の対象の開始アドレス
* d4.l = (hash.w)(文字数 - 1)
move.l d4,(a4)+ * (hash.w)(文字数 - 1)
move.l a2,(a4)+ * 名前
move.l (a0)+,(a4)+ * パラメータリストを指すポインタ
move.l (a1)+,(a4)+ * 実行アドレス
* おんなじ名前の関数もあるかもしれないが、そのまま登録してまおう
* 上から一致を見ていくから、先に登録したものが優先となるはず
addq.w #1,d6
addq.l #1,a5 * $00
tst.b (a5)
bne fi_loop1
fi_loop1_end:
rts
* プログラム全体から 'func' の文字列を探しだし、
* 内部関数の宣言なら登録する。
内部関数:
move.l a4,内部関数para
lea.l -$10*$400(sp),sp * 内部関数の個数の上限 1024 (大丈夫……かな?)
movea.l sp,a4 * 内部関数buf_tmp
move.l a4,内部関数buf
lea.l tmp,a0 * func を探すための BM法テーブル
move.l #$04040404,d0
moveq #32/4-1,d1
@@:
move.l d0,(a0)+
dbra d1,@b
move.l #$05050505,d0
moveq #(256-32)/4-1,d1
@@:
move.l d0,(a0)+
dbra d1,@b
lea.l tmp,a0
move.b #4,' '(a0)
move.b #3,'f'(a0)
move.b #2,'u'(a0)
move.b #1,'n'(a0)
clr.b 'c'(a0)
move.w #-1,内部関数個数
addq.l #4,a5
search_func_loop:
clr.w d0
move.b (a5),d0
move.b (a0,d0.w),d0
bne func_next
moveq #4+1,d0
movea.l a5,a1
cmpi.b #'n',-(a1)
bne func_next
cmpi.b #'u',-(a1)
bne func_next
cmpi.b #'f',-(a1)
bne func_next
@@:
move.b -(a1),d1 * 前の文字は空白・行番号を飛ばすと改行 ($a) でなきゃ
cmpi.b #32,d1
beq @b
cmpi.b #9,d1
beq @b
cmpi.b #'9',d1
bhi func_next
cmpi.b #'0',d1
bcc @b
cmpi.b #$a,d1
bne func_next
move.b 1(a5),d1 * 次の文字(空白・TAB)
cmpi.b #' ',d1
beq func_hit
cmpi.b #9,d1
bne func_next
func_hit:
movem.l a0/a2,-(sp)
bsr 内部関数登録
movem.l (sp)+,a0/a2
moveq #4,d0
func_next:
adda.w d0,a5
cmpa.l a2,a5
bcs search_func_loop
movea.l 内部関数para,a4
move.l a4,内部関数buf
move.w 内部関数個数,d1 * buf_tmp からコピー
bmi 1f
movea.l sp,a0
@@:
move.l (a0)+,(a4)+
move.l (a0)+,(a4)+
move.l (a0)+,(a4)+
move.l (a0)+,(a4)+
dbra d1,@b
1:
lea.l $10*$400(sp),sp
rts
内部関数登録:
addq.l #1,a5
* 型を得る(省略なら int )
bsr 型getS
* (INT,STR,CHAR,FLOAT)
* d1.w 型を返す( 0, 2, 4, 6)
move.w d1,-(sp)
bsr first_check_a5_in_line
* ハッシュ値を計算しながら、文字数を数える
bsr hash
* a2.l = 元の対象の開始アドレス
* d4.l = (hash.w)(文字数-1)
tst.w d4
bmi func文err
bsr statement_check
* 一致しなければ d0 = 0
tst.w d0
bne func_double_def
bsr function_check
* d0.w = ヒットした関数の返り値の型 ( = 0 : 該当関数無し )
tst.w d0
bne func_double_def0
* 内部関数登録
addq.w #1,内部関数個数
move.l d4,(a4)+ * (hash.w)(文字数 - 1)
bsr 名前登録 * a2,d4 破壊
move.l a0,(a4)+ * 名前
movea.l 内部関数para,a3
move.l a3,(a4)+ * パラメータリストを指すポインタ
clr.l (a4)+ * 実行アドレス(念のためクリアしとく)
cmpi.b #'(',(a5)+
bne func文err0
bsr first_check_a5_in_line
cmpi.b #')',d0
beq 内部関数登録loop_end
内部関数登録loop:
bsr first_check_a5_in_line
bsr hash * 引き数名(今は無視)
cmpi.b #'(',(a5)
bne @f
bsr 配列引き数
bra 内部関数登録cont
@@:
moveq #$0,d1 * int引き数
* bsr first_check_a5_in_line
cmpi.b #';',(a5)
bne @f
addq.l #1,a5
bsr 型getS * d0/d1:return, a0/a2:破壊
* d0 = 0 省略せず
* = 1 省略
bne func文err0
@@:
move.w _引き数の型(pc,d1.w),(a3)+
内部関数登録cont:
bsr first_check_a5_in_line
addq.l #1,a5
cmpi.b #',',d0
beq 内部関数登録loop
cmpi.b #')',d0
bne func文err0
内部関数登録loop_end:
move.w (sp)+,d1 * 返り値の型
move.w _返り値の型(pc,d1.w),(a3)+
move.l a3,内部関数para
rts
_引き数の型:
.dc.w $0002,$0008,$0004,$0001
_返り値の型:
* .dc.w int_ret,str_ret,char_ret,float_ret
.dc.w $8001,$8003,$8002,$8000
* ^^^^^ 新設
配列引き数:
btst #fnc_dimF,d7
beq 配列引き数err
movem.l d2/d3,-(sp)
moveq #-1,d1 * 次元 - 1
moveq #0,d2 * 添字大きさ指定フラグ
lea.l 6(a3),a2 * $8080.w, 型.b, 次元-1.b, 添字flag.w
@@:
addq.l #1,a5 * '(',','
bsr first_check_a5_in_line
cmpi.b #')',d0
beq 2f
cmpi.b #',',d0
bne 1f
addq.w #1,d1 * 次元++
clr.w (a2)+ * 一応
bra @b
1:
bsr int定数get * 添字大きさ
cmpi.l #$10000,d0
bcc func文err0
addq.w #1,d1 * 次元++
move.w d0,(a2)+
moveq #$f,d0
sub.w d1,d0
bset d0,d2 * 添字大きさ指定フラグ set
bsr first_check_a5_in_line
cmpi.b #')',d0
beq 3f
cmpi.b #',',d0
beq @b
bra func文err0
2:
addq.w #1,d1 * 次元++
clr.w (a2)+ * 一応
3:
addq.l #1,a5
tst.w d2
bne 拡張配列引き数 * 添字大きさ指定フラグが一個でもあれば
cmpi.w #1,d1
bhi 拡張配列引き数 * 三次元以上なら
beq @f
moveq #$0020,d2 *普通の1次元
bra 1f
@@:
moveq #$0040,d2 *普通の2次元
1:
moveq #$0,d1 * int引き数
bsr first_check_a5_in_line
cmpi.b #';',d0
bne @f
addq.l #1,a5
bsr 型getS * d0/d1:return, a0/a2:破壊
* d0 = 0 省略せず
* = 1 省略
bne func文err0
@@:
lea.l _引き数の型(pc),a0
add.w (a0,d1.w),d2 * 2次元以下配列型指定
move.w d2,(a3)+
movem.l (sp)+,d2/d3
rts
拡張配列引き数:
cmpi.w #10,d1
bcc func文err0 * 11次元以上
move.l a2,-(sp)
move.w #$8080,(a3)+ * 拡張配列引き数
bsr first_check_a5_in_line
moveq #0,d0 * int
cmpi.b #';',(a5)
bne @f
addq.l #1,a5
movem.l d1/a1,-(sp)
bsr 型getS * d0/d1:return, a0/a2:破壊
* d0 = 0 省略せず
* = 1 省略
bne func文err0
move.w _引き数の型2(pc,d1.w),d0
movem.l (sp)+,d1/a1
@@:
or.w d1,d0
move.w d0,(a3)+ * 型+次元-1
move.w d2,(a3)+ * 添字大きさ指定フラグ
movea.l (sp)+,a3
movem.l (sp)+,d2/d3
rts
_引き数の型2:
.dc.w $0000,$0100,$0200,$8000
配列引き数err:
bsr line算出
ERRORS 77 * 配列名を表示
func文err0:
movea.l -$10+4(a4),a2
move.w -$10+2(a4),d4
bsr line算出
ERRORS 39 * 関数名を表示
func文err:
bsr line算出
ERROR 39
func_double_def0:
movea.l -$10+4(a3),a2
move.w -$10+2(a3),d4
func_double_def:
bsr line算出
ERRORS 40
* 何行目かを出す
line算出:
move.l a5,d1
sub.l program_area,d1
moveq #1,d2
line算出loop:
cmpi.b #$a,-(a5)
bne @f
addq.l #1,d2
@@:
subq.l #1,d1
bne line算出loop
move.l d2,行数
rts
.xdef fnc書替sub
fnc書替sub:
bclr #fnckeyF,d7 * FKEY 書き替えるよ
beq @f
btst #fncautoF,d7
bne @f
bset #fnckeyF,d7 * やっぱり書き替えないよ
bset #fncwarnF,d7
bne @f
WARN 67
@@:
rts
FKEY戻す:
tst.w fkeyflag
beq @f
pea.l b_initbuf
move.w #$100,-(sp)
DOS _FNCKEY
addq.l #6,sp
@@:
rts
.xdef FKEYset
FKEYset:
bsr make_keydata
btst #fnckeyF,d7
bne @f
pea.l b_initbuf
clr.w -(sp)
DOS _FNCKEY
pea.l _SP上限(a6)
move.w #$100,-(sp)
DOS _FNCKEY
lea.l 12(sp),sp
move.w #-1,fkeyflag
@@:
rts
make_keydata:
lea.l _b_keydata(pc),a1
lea.l _SP上限(a6),a2
moveq #0,d0
moveq #(($20*20)+(6*12))/8-1,d1
movea.l a2,a0
@@:
move.l d0,(a0)+
move.l d0,(a0)+
dbra d1,@b
moveq #10-1,d1
1:
movea.l a2,a0
@@:
move.b (a1)+,(a0)+
bne @b
lea.l $20(a2),a2
dbra d1,1b
lea.l $20*10(a2),a2
moveq #12-1,d1
@@:
move.b (a1)+,(a2)
addq.l #6,a2
dbra d1,@b
rts
* XC ver.2 のライブラリのソース KEYDATA.S から改変
_b_keydata:
dc.b 'files ',13,0
dc.b 'load ',13,0
dc.b 'auto ',0
dc.b 'list ',13,0
dc.b 'run ',13,0
dc.b '/*',0
dc.b 'width ',0
dc.b 'end',0
dc.b 'func ',0
dc.b 'system',0
dc.b $0e,$0f,$01,$7f,$1e,$1d,$1c,$1f,$0c,$16,$0b,$15
.even
* 外部関数のさまざまなルーチンを呼ぶ
Fルーチン:
movem.l d0-d7/a0-a6,-(sp)
move.w 関数file数,d0
bmi no_func_file1
movea.l 関数list,a5
@@:
movea.l (a5)+,a0
move.l (a0,d1.w),a0
movem.l d0/d1/a5,-(sp)
jsr (a0) * run 実行時の初期化ルーチン
movem.l (sp)+,d0/d1/a5
dbra d0,@b
no_func_file1:
movem.l (sp)+,d0-d7/a0-a6
rts
* コマンドラインの評価
com_est:
tst.b (a2)+
beq help
ce_loop:
move.b (a2)+,d0
beq help
cmpi.b #$20,d0
bls ce_loop
cmpi.b #'-',d0
bne ce_file
moveq #$20,d0
or.b (a2)+,d0
cmpi.b #'c',d0
beq sw_c
cmpi.b #'e',d0
beq sw_e
cmpi.b #'f',d0
beq sw_f
.ifdef _DEBUG
cmpi.b #'d',d0
beq sw_d
.endif
bra help
sw_f:
movea.l a2,a0
FPACK __STOL
movea.l a0,a2
move.w d0,_FREEMEM(a6)
bra ce_loop
sw_e:
movem.l EXTENDmask,d1/d2 * OFFmask/ONmask
lea.l _ext_flag(pc),a0
@@:
move.b (a2)+,d0
subi.b #'A',d0
bcs sw_e_end
cmpi.b #26,d0
bcc sw_e_off
move.b (a0,d0.w),d0
beq help
bset d0,d2 * ONmask
bra @b
sw_e_off:
subi.b #'a'-'A',d0
bcs help
cmpi.b #26,d0
bcc sw_e_off
move.b (a0,d0.w),d0
beq help
bclr d0,d1 * OFFmask
bra @b
sw_e_end:
movem.l d1/d2,EXTENDmask
subq.l #1,a2
bra ce_loop
sw_c:
lea.l cnf_filename,a0
bsr ce_sub0
bra ce_loop
.ifdef _DEBUG
sw_d:
movea.l a2,a0
FPACK __STOL
movea.l a0,a2
lea.l break行数(pc),a0
move.l d0,(a0)
bra ce_loop
break行数: .dc.l -1
.endif
ce_file:
subq.l #1,a2
lea.l basic_filename,a0
bsr ce_sub
* move.l a2,command_line
* move.l command_line,a2
bsr b_argv展開
rts
b_argv展開:
addq.l #2,a4 * 項目をロングワード境界に
move.l a4,b_argv
clr.l (a4)+ * 次を指す offset (dummy)
move.l #$0000_00ff,(a4)+ * (次元 - 1)_(データサイズ)
move.l a4,-(sp)
addq.l #2,a4 * 要素数
lea.l _SP上限(a6),a1
move.l a1,-(sp)
pea.l basic_filename
DOS _NAMECK
addq.l #8,sp
movea.l a4,a0
bsr barg_sub * drive & path
lea.l 2+65+_SP上限(a6),a1
bsr barg_sub * file name
lea.l 2+65+19+_SP上限(a6),a1
bsr barg_sub * ext name
lea.l $100(a4),a4
moveq #0,d1 * 要素数
barg_loop:
tst.b (a2)
beq barg_end
movea.l a4,a0
bsr ce_sub
lea.l $100(a4),a4
addq.w #1,d1 * 要素数
bra barg_loop
barg_end:
movea.l (sp)+,a0
move.w d1,(a0)
addq.w #1,d1
move.l d1,b_argc
rts
barg_sub:
move.b (a1)+,(a0)+
bne barg_sub
subq.l #1,a0
rts
ce_sub0:
move.b (a2)+,d0
beq help
cmpi.b #$20,d0
bls ce_sub0
subq.l #1,a2
ce_sub:
move.b (a2)+,d0
cmpi.b #$20,d0
bls @f
move.b d0,(a0)+
bra ce_sub
@@:
clr.b (a0)
subq.l #1,a2
@@:
move.b (a2)+,d0
beq @f
cmpi.b #$20,d0
bls @b
@@:
subq.l #1,a2
rts
* テキストのパレット初期化 * by Eriko Tachibana
.xdef init_tpal
init_tpal:
moveq #3,d1
moveq #-2,d2 * システムの既定値 の意
@@
IOCS _TPALET * 一応
dbra d1,@b
rts
.xdef 最左カラム
最左カラム:
movem.l d0-d2,-(sp)
moveq #-1,d1
IOCS _B_LOCATE
swap d0
tst.w d0
beq @f
pea.l crlf(pc) * カーソルを画面最左カラムに
DOS _PRINT
addq.l #4,sp
@@:
movem.l (sp)+,d0-d2
rts
.xdef dec_print
dec_print:
movem.l d0-d2/a0,-(sp)
move.l 4+4*4(sp),d2
bmi dec_minus
bsr DECP
move.b #$20,-(a0)
bra dec_plus
dec_minus:
neg.l d2
bsr DECP
move.b #'-',-(a0)
dec_plus:
move.l a0,-(sp)
DOS _PRINT
addq.l #4,sp
movem.l (sp)+,d0-d2/a0
rts
DECP:
lea.l $100+tmp,a0
move.w #$20_00,-(a0)
moveq #10,d1
decp2:
swap d2
moveq #0,d0
move.w d2,d0
divu d1,d0
beq decp3
move.w d0,d2
swap d2
move.w d2,d0
divu d1,d0
move.w d0,d2
swap d0
addi.b #$30,d0
move.b d0,-(a0)
bra decp2
decp3:
swap d2
decp4:
divu d1,d2
swap d2
addi.b #$30,d2
move.b d2,-(a0)
clr.w d2
swap d2
bne decp4
rts
* a5 の指す中間言語のアドレスが何行目かを計算して '行数' に返す
.xdef I行数算出
I行数算出:
moveq #0,d1
movea.l 4+中間言語行数,a3
move.l 中間言語,a1
@@:
bsr bufget
adda.w d0,a1
addq.w #1,d1
cmpa.l a5,a1
bcs @b
subq.l #1,d1
move.l d1,行数
rts
* メモリの最後尾(mem_last)から、 d0.w だけのメモリを確保して、
* アドレスを a0に返す
.xdef malloc
malloc:
movea.l mem_last,a0
suba.w d0,a0
move.l a0,mem_last
rts
* 鎖状のバッファ(size = CbufSIZE * word )を malloc して、d0.w を書き込む
* d1.w/a0-a1 破壊
.xdef buf書込L
buf書込L:
move.l 4(sp),-(sp)
swap d0
bsr buf書込
swap d0
bsr buf書込
addq.l #4,sp
rts
.xdef buf書込
buf書込:
movea.l 4(sp),a1
addq.w #1,8(a1)
move.w 8(a1),d1
andi.w #CbufSIZE-1,d1
bne 3f
move.w d0,d1
move.w #CbufSIZE*2+4,d0
bsr malloc
move.w d1,d0
move.w 8(a1),d1
bne 1f
move.l a0,4(a1) * 先頭登録
bra 4f
1:
movea.l (a1),a1 * 今の鎖の最後尾
move.l a0,(a1) * 次の鎖へのつなぎ
movea.l 4(sp),a1 * もう一回復活
bra 4f
3:
move.l (a1),a0 * 今の書き込みポインタ
4:
move.w d0,(a0)+
move.l a0,(a1) * 書き込みポインタ登録
rts
* 鎖状のバッファ(size = CbufSIZE * word )の先頭を a3 で指定して
* d1 で指されたデータを d0.w に返す
.xdef bufget
bufget:
move.l a3,-(sp)
move.w d1,d0
@@:
subi.w #CbufSIZE,d0
bcs @f
movea.l CbufSIZE*2(a3),a3
bra @b
@@:
addi.w #CbufSIZE,d0
add.w d0,d0
move.w (a3,d0.w),d0
movea.l (sp)+,a3
rts
* 鎖状のバッファ(size = CbufSIZE * word )の先頭を a3 で指定して
* d1 で指された位置に d2 を書き込む (d0.w 破壊)
.xdef bufput
bufput:
move.l a3,-(sp)
move.w d1,d0
@@:
subi.w #CbufSIZE,d0
bcs @f
movea.l CbufSIZE*2(a3),a3
bra @b
@@:
addi.w #CbufSIZE,d0
add.w d0,d0
move.w d2,(a3,d0.w)
movea.l (sp)+,a3
rts
.xdef bufgetL
bufgetL:
bsr bufget
swap d0
addq.w #1,d1
bsr bufget
subq.w #1,d1
rts
bufputL:
swap d2
bsr bufput
swap d2
addq.w #1,d1
bsr bufput
subq.w #1,d1
rts
* 鎖バッファ が連結でなかったら、つなぐ
.xdef chain連結
chain連結:
move.w 8(a1),d0
cmpi.w #CbufSIZE,d0
bcs 連結必要無し
move.w d0,d1
add.w d0,d0
bsr malloc
movea.l 4(a1),a2
move.l a0,4(a1)
move.w #CbufSIZE,d0
@@:
move.w (a2)+,(a0)+
subq.w #1,d0
dbeq d1,@b
bne 連結終
movea.l (a2),a2
move.w #CbufSIZE,d0
dbra d1,@b
連結終:
move.l a0,(a1)
連結必要無し:
rts
.ifdef _DEBUG
func情報:
movem.l d0-d7/a0-a5,-(sp)
func情報_loop:
pea.l func情報_name(pc)
DOS _PRINT
addq.l #4,sp
lea.l tmp,a5
move.l a5,-(sp)
move.w #$ff00,(a5)+
DOS _GETS
pea.l crlf(pc)
DOS _PRINT
addq.l #8,sp
tst.b (a5)
beq func情報_end
bsr hash
bsr function_check
tst.w d0
beq func情報_無し
tst.w d3
bmi func情報_内部
pea.l func情報_1(pc)
DOS _PRINT
move.l -$10+$c(a3),d0 * 実行アドレス
lea.l tmp,a0
move.l a0,(sp)
FPACK __HTOS
DOS _PRINT
pea.l crlf(pc)
DOS _PRINT
addq.l #8,sp
bra func情報_loop
func情報_内部:
pea.l func情報_3(pc)
bra @f
func情報_無し:
pea.l func情報_2(pc)
@@:
DOS _PRINT
addq.l #4,sp
bra func情報_loop
func情報_end:
movem.l (sp)+,d0-d7/a0-a5
rts
func情報_name:
.dc.b '関数名:',0
func情報_1:
.dc.b '実行アドレス : ',0
func情報_2:
.dc.b '該当関数無し',13,10,0
func情報_3:
.dc.b '内部関数',13,10,0
.even
DEBUG情報:
IOCS _ONTIME
sub.l _comptime(pc),d0
lea.l tmp,a0
move.l a0,-(sp)
moveq #6,d1
FPACK __IUSING
move.l #'/100',(a0)+
move.w #$0d0a,(a0)+
clr.b (a0)
DOS _PRINT
addq.l #4,sp
pea.l M01(pc)
DOS _PRINT
addq.l #4,sp
moveq #0,d0
move.w _FREEMEM(a6),d0
move.l d0,-(sp)
bsr dec_print
pea.l Mkb(pc)
DOS _PRINT
addq.l #8,sp
pea.l M02(pc)
DOS _PRINT
addq.l #4,sp
lea.l tmp,a0
move.l a0,-(sp)
move.l mem_last,d0
sub.l 変数area,d0
FPACK __HTOS
DOS _PRINT
move.w #'(',-(sp)
DOS _PUTCHAR
addq.l #2,sp
move.l 変数area,d0
lea.l tmp,a0
FPACK __HTOS
DOS _PRINT
move.w #'-',-(sp)
DOS _PUTCHAR
addq.l #2,sp
move.l mem_last,d0
lea.l tmp,a0
FPACK __HTOS
DOS _PRINT
move.w #')',-(sp)
DOS _PUTCHAR
addq.l #2,sp
pea.l crlf(pc)
DOS _PRINT
addq.l #8,sp
move.w #$20,-(sp) * DEBUG
pea.l filename(pc)
DOS _CREATE
movea.l 中間言語,a0
suba.l a0,a4
movem.l a0/a4,-(sp)
move.w d0,-(sp)
DOS _WRITE
DOS _CLOSE
lea.l 16(sp),sp
move.w #$20,-(sp) * DEBUG
pea.l filename2(pc)
DOS _CREATE
move.l 変数INIT,d2
move.l 4+変数INIT,d1
* move.l 引数INIT,d2
* move.l 4+引数INIT,d1
sub.l d1,d2
movem.l d1/d2,-(sp)
move.w d0,-(sp)
DOS _WRITE
DOS _CLOSE
lea.l 16(sp),sp
rts
.endif
.end